home *** CD-ROM | disk | FTP | other *** search
/ Gamers Delight 2 / Gamers Delight 2.iso / Aminet / game / role / pinfocom_3_0.lha / Source / getopt.c < prev    next >
C/C++ Source or Header  |  1992-10-22  |  5KB  |  256 lines

  1. /*
  2.  * getopt.c  - Simulates getopt(1) and getopt(3)
  3.  *
  4.  * This program (or library) simulates the getopt(1) program (and
  5.  * the getopt(3) library function).
  6.  *
  7.  * Copyright:
  8.  *      Copyright (C) 1988  Paul D. Smith
  9.  *      Permission is given to use, modify, and distribute this code
  10.  *      in any manner the user sees fit, as long as this C comment
  11.  *      remains intact.
  12.  *
  13.  *      This code is distributed in the hope that it will be useful,
  14.  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  16.  *
  17.  * Author(s):
  18.  *  pds - Paul D. Smith (paul_smith@dg.com: was pds@cs.cmu.edu)
  19.  *
  20.  * History:
  21.  *  15 Apr 88 pds - Created.
  22.  */
  23.  
  24. /*
  25.  * $Header: RCS/getopt.c,v 3.0 1992/10/21 16:56:19 pds Stab $
  26.  */
  27.  
  28. #include <stdio.h>
  29.  
  30.  
  31. #ifdef GETOPT_DEBUG
  32. #   define  DB(_x)      fprintf _x
  33. #else
  34. #   define  DB(_x)
  35. #endif
  36.  
  37. #define USAGE           "usage: getopt legal-args $*\n"
  38.  
  39. #define NO_OPTARG       ": option requires an argument -- "
  40. #define NO_OPT          ": illegal option -- "
  41.  
  42. #define IS_VALID(_c)    (((_c) != '\0') && ((_c) != ':'))
  43. #define IS_OPT(_s)      ((*(_s) == '-') && IS_VALID((_s)[1]))
  44.  
  45.  
  46. char *optarg=NULL;
  47. int optind=1, opterr=1;
  48.  
  49.  
  50. int getopt(argc, argv, optstring)
  51. int argc;
  52. char **argv;
  53. char *optstring;
  54. {
  55.     register char *argp, *optp;
  56.     char *errp;
  57.     static int prev_offset=0;
  58.     int c;
  59.  
  60.     optarg = NULL;
  61.  
  62.     parse_next:
  63.     if (optind >= argc)
  64.     {
  65.         DB((stderr, "getopt: no more args (optind=%d)\n", optind));
  66.         return (-1);
  67.     }
  68.  
  69.     /*
  70.      * Do we have a real option?  Must be a "-?*" format, where
  71.      * ? cannot be ':'.
  72.      */
  73.     argp = argv[optind];
  74.  
  75.     if (!IS_OPT(argp))
  76.     {
  77.         DB((stderr, "getopt: not an option = %s\n", argp));
  78.         return (-1);
  79.     }
  80.  
  81.     /*
  82.      * Do we have a '--' argument?  Skip it & we're done.
  83.      */
  84.     if (argp[1] == '-')
  85.     {
  86.         DB((stderr, "getopt: end of options = %s\n", argp));
  87.         ++optind;
  88.         return (-1);
  89.     }
  90.  
  91.     /*
  92.      * Skip into the middle of the last option we were parsing
  93.      */
  94.     argp += ++prev_offset;
  95.  
  96.     /*
  97.      * Is this the end of the argument?  If so parse the next arg.
  98.      */
  99.     if (*argp == '\0')
  100.     {
  101.         ++optind;
  102.         prev_offset = 0;
  103.         goto parse_next;
  104.     }
  105.  
  106.     /*
  107.      * Otherwise, find the option in the optstring.
  108.      */
  109.     for (optp=optstring; *optp != '\0'; ++optp)
  110.     {
  111.         if (*optp == *argp)
  112.         {
  113.             DB((stderr, "getopt: found option = %c\n", *argp));
  114.             c = (int)*(argp++);
  115.  
  116.             /*
  117.              * Process option-arguments
  118.              */
  119.             if (*(++optp) == ':')
  120.             {
  121.                 DB((stderr, "getopt: Requires argument, ="));
  122.                 prev_offset = 0;
  123.  
  124.                 if (*argp == '\0')
  125.                 {
  126.                     DB((stderr, "(next arg) "));
  127.                     if (++optind == argc)
  128.                     {
  129.                         errp = NO_OPTARG;
  130.                         goto error;
  131.                     }
  132.                     argp = argv[optind];
  133.                 }
  134.  
  135.                 optarg = argp;
  136.                 ++optind;
  137.                 DB((stderr, " %s\n", optarg));
  138.                 return (c);
  139.             }
  140.  
  141.             /*
  142.              * Otherwise it's a simple option.
  143.              */
  144.             if (*argp == '\0')
  145.             {
  146.                 ++optind;
  147.                 prev_offset = 0;
  148.             }
  149.  
  150.             return (c);
  151.         } /* if */
  152.     }/* for */
  153.  
  154.     /*
  155.      * We have come to the end of the optstring without finding
  156.      * an option, so print & return an error.
  157.      */
  158.     c = *argp;
  159.     if (*(++argp) == '\0')
  160.     {
  161.         ++optind;
  162.         prev_offset = 0;
  163.     }
  164.     errp = NO_OPT;
  165.  
  166. error:
  167.     if (opterr)
  168.     {
  169.         fputs(argv[0], stderr);
  170.         fputs(errp, stderr);
  171.         putc(c, stderr);
  172.         putc('\n', stderr);
  173.     }
  174.     return ('?');
  175. }
  176.  
  177.  
  178. #ifdef EXE
  179.  
  180. /*
  181.  * This program simulates the getopt(1) program.
  182.  */
  183.  
  184.  
  185. int main(argc, argv)
  186. int argc;
  187. char **argv;
  188. {
  189.     register char **av, *cp, *op;
  190.     int c, i;
  191.     char options[1024];
  192.  
  193.     /*
  194.      * Make sure we've got something:
  195.      */
  196.     if (argc < 2)
  197.     {
  198.         fputs(USAGE, stderr);
  199.         exit (2);
  200.     }
  201.  
  202.     /*
  203.      * Get beyond the optstring, which is the first argument.
  204.      */
  205.     ++optind;
  206.     op = options;
  207.  
  208.     while ((c = getopt(argc, argv, argv[1])) != -1)
  209.     {
  210.         DB((stderr, "main: got opt %c\n", c));
  211.         if (c == '?')
  212.         {
  213.             exit (2);
  214.         }
  215.  
  216.         *(op++) = '-';
  217.         *(op++) = c;
  218.  
  219.         if (optarg)
  220.         {
  221.             DB((stderr, "main: optarg = %s\n", optarg));
  222.             *(op++) = ' ';
  223.  
  224.             for (cp = optarg; *cp != '\0'; *(op++) = *(cp++))
  225.             {}
  226.         }
  227.  
  228.         *(op++) = ' ';
  229.     }/*while*/
  230.  
  231.     DB((stderr, "main: End of options\n"));
  232.  
  233.     *op = '\0';
  234.     fputs(options, stdout);
  235.     putchar('-');
  236.     putchar('-');
  237.     putchar(' ');
  238.  
  239.     for (i = optind, av = &argv[i]; i < argc; ++i, ++av)
  240.     {
  241.         DB((stderr, "main: regular arg = %s\n", *av));
  242.  
  243.         fputs(*av, stdout);
  244.         if (i != argc)
  245.         {
  246.             putchar(' ');
  247.         }
  248.     }
  249.     putchar('\n');
  250.  
  251.     exit (0);
  252. }
  253.  
  254.  
  255. #endif  /* EXE */
  256.